package lifeOfAFish;

import lifeOfAFish.scenegraph.*;
import lifeOfAFish.scenegraph.geom.*;
/**
 * Class for running a particle system of bubbles 
 * @author Erik Bonner
 *
 */
public class Bubbles extends Entity {

	//
	// Fields
	//

	// class for representing a bubble
	private class Particle{
		sgVec3 pos;
		sgVec3 vel;
		float alpha = 0;
		sgTransform transNode;
		sgGeomSphere geom;
		sgMaterial mat;
		boolean active = false;
		
		Particle(sgVec3 initPos){
			pos = new sgVec3(initPos);
			vel = new sgVec3(0.0f, 0.0f, 0.0f);
			transNode = new sgTransform();
			geom = new sgGeomSphere(0.02f);
			transNode.addChild(geom);
			
			// set up the geometry properties
			mat = new sgMaterial();
			mat = new sgMaterial();
			mat.setAmbient(0.7f, 0.7f, 0.7f, 0.3f);
			mat.setDiffuse(0.7f, 0.7f, 0.7f, 0.3f);
			mat.setSpecular(0.9f, 0.9f, 0.9f, 0.3f);
			geom.setMaterial(mat);
			geom.setOpaque(false);
			geom.setActive(false);
			
		}
		
		void setActive(boolean f){
			active = f;
			geom.setActive(f);
		}
	}

	private static final int NumBubbles = 10;
	private Particle[] m_particles = new Particle[NumBubbles]; 
	private sgVec3 m_origin = new sgVec3(0.0f, 0.0f, 0.0f);
	private float m_speedBase = 0.002f;
	private float m_speedFactor = 0.002f;
	private float m_height = 1.0f;

	//
	// Constructors
	//
	public Bubbles () { };

	public void setOrigin(sgVec3 o){
		m_origin = o;
		for(int c = 0; c < NumBubbles; c++){
			m_particles[c].pos = o.clone();
		}
	}
	
	public void setHeight(float h){
		m_height = h;
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	/**
	 * Initialise the bubbles system
	 */
	public void init() {
		for(int c = 0; c < NumBubbles; c++){
			m_particles[c] = new Particle(m_origin);
			float s = getNewSpeed(); 
			m_particles[c].vel = new sgVec3(calcXSpeed(s) , s, 0.0f);
			m_node.addChild(m_particles[c].transNode);
		}
		
	}
	@Override
	public void update() {
		
		// move the particles
		for(int c = 0; c < NumBubbles; c++){
			
			if(!m_particles[c].active){
				if (Math.random() < 0.01f) m_particles[c].setActive(true);
				else continue;
			}
			
			m_particles[c].pos = sgVec3.add(m_particles[c].pos, m_particles[c].vel);
			m_particles[c].transNode.translate(m_particles[c].pos.getV());
			
			if(m_particles[c].pos.getY() > this.m_height){
				m_particles[c].pos = m_origin.clone();
				float s = getNewSpeed(); 
				m_particles[c].vel = new sgVec3(calcXSpeed(s) , s, 0.0f);
				m_particles[c].setActive(false);
			}
		}
		

	}
	
	private float getNewSpeed(){
		return m_speedBase + m_speedFactor*(float)Math.random();
	}
	
	private float calcXSpeed(float s){
		boolean flag = (Math.random() > 0.5f);
		float sign = flag?1:-1;
		return sign*0.1f*(float)(Math.random())*s;
	}


}
